package com.nsgf.library.ui.page;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.webkit.WebSettings;
import android.webkit.WebViewClient;
import android.graphics.Bitmap;
import android.media.MediaMetadataRetriever;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.core.widget.NestedScrollView;
import androidx.lifecycle.Observer;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.android.material.bottomsheet.BottomSheetBehavior;

import static com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_COLLAPSED;
import static com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_HIDDEN;

import com.kunminx.architecture.ui.page.DataBindingConfig;
import com.kunminx.architecture.ui.state.State;
import com.nsgf.library.BR;
import com.nsgf.library.R;
import com.bumptech.glide.Glide;
import com.nsgf.library.data.bean.UserInfo;
import com.nsgf.library.data.bean.WeatherBean;
import com.nsgf.library.data.bean.WorkOrderDetailBean;
import com.nsgf.library.data.response.DataResult;
import com.nsgf.library.data.response.ResponseStatus;
import com.nsgf.library.databinding.ActivityPatrolBinding;
import com.nsgf.library.domain.request.AccountRequester;
import com.nsgf.library.matisse.Matisse;
import com.nsgf.library.matisse.MimeType;
import com.nsgf.library.photopicker.PhotoPicker;
import com.nsgf.library.photopicker.utils.PermissionsUtils;
import com.nsgf.library.photopicker.widget.MultiPickResultView;
import com.nsgf.library.photopicker.widget.PhotoAdapter;
import com.nsgf.library.service.LocationService;
import com.nsgf.library.ui.adapter.WeatherListAdapter;
import com.nsgf.library.ui.adapter.StructureComponentAdapter;
import com.nsgf.library.data.bean.StructureComponentBean;
import com.nsgf.library.ui.page.manager.ManagerWorkOrderDamDetailsActivity;
import com.nsgf.skjz.utils.Kits;
import com.nsgf.skjz.utils.ToastUtils;
import com.google.gson.JsonObject;
import com.google.gson.JsonArray;
import com.nsgf.skjz.utils.Utils;

import okhttp3.MediaType;
import okhttp3.RequestBody;

import static com.nsgf.library.photopicker.PhotoPicker.KEY_SELECTED_PHOTOS;
import static com.nsgf.library.ui.page.manager.WorkOrderMapActivity.getJsonObject;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Queue;
import java.util.Set;

/**
 * 工程巡查页面
 */
public class PatrolActivity extends BaseActivity {

    PatrolStates states;
    private ActivityPatrolBinding mBinding;
    private AccountRequester mAccountRequester;

    private int selectedWeatherIndex = 0; // 0-晴 1-阴 2-雨 3-雪
    private int checkResult = 0; // 0-正常 1-异常

    private WeatherListAdapter mAdapter;
    private StructureComponentAdapter mStructureComponentAdapter;
    private List<StructureComponentBean> structureComponentList = new ArrayList<>(); // 结构组件列表
    private List<WorkOrderDetailBean.FileDto> selectedVideos = new ArrayList<>(); // 已选择的视频列表
    private static final int REQUEST_CODE_VIDEO = 1001; // 视频选择请求码
    private BottomSheetBehavior<NestedScrollView> mBottomSheetBehavior; // 底部抽屉行为


    private Handler handler = new Handler();
    private Runnable runnable;


    long time;

    private void updateTimer() {
        time = time + 1000;
        states.patrolDuration.set(Kits.Date.millisToHMS(time));

    }

    private void startTimer() {
        runnable = new Runnable() {
            @Override
            public void run() {
                updateTimer();
                handler.postDelayed(this, 1000); // 1000毫秒后再次执行
            }
        };
        handler.post(runnable);
    }

    @Override
    protected void initViewModel() {
        states = getActivityScopeViewModel(PatrolStates.class);
        mAccountRequester = getActivityScopeViewModel(AccountRequester.class);
    }

    @Override
    protected DataBindingConfig getDataBindingConfig() {
        mAdapter = new WeatherListAdapter(this);
        mStructureComponentAdapter = new StructureComponentAdapter(this);
        return new DataBindingConfig(R.layout.activity_patrol, BR.vm, states)
                .addBindingParam(BR.adapter, mAdapter)
                .addBindingParam(BR.click, new ClickProxy());
    }

    @SuppressLint("SetJavaScriptEnabled")
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding = (ActivityPatrolBinding) getBinding();

        // 初始化标题栏
        initTitleBar();

        // 初始化WebView地图
        initWebView();

        // 初始化数据
        initData();

        // 初始化观察者
        initObserver();

        // 加载天气数据
        loadWeatherData();

        // 初始化图片选择器
        initImagePicker();

        // 初始化底部抽屉
        initBottomSheet();
    }

    /**
     * 初始化底部抽屉
     */
    private void initBottomSheet() {
        mBottomSheetBehavior = BottomSheetBehavior.from(mBinding.bottomSheet);
        // 设置默认状态为收起（显示peekHeight）
        mBottomSheetBehavior.setState(STATE_COLLAPSED);

        // 设置可以拖拽隐藏
        mBottomSheetBehavior.setHideable(true);

        // 添加状态回调
        mBottomSheetBehavior.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
            @Override
            public void onStateChanged(@NonNull View bottomSheet, int newState) {
                // 如果完全隐藏，则恢复到收起状态
                if (newState == STATE_HIDDEN) {
                    mBottomSheetBehavior.setState(STATE_COLLAPSED);
                }
            }

            @Override
            public void onSlide(@NonNull View bottomSheet, float slideOffset) {
                // 滑动过程中的回调，可以用于实现动画效果
            }
        });
    }

    /**
     * 初始化标题栏
     */
    private void initTitleBar() {
        mBinding.titlebar.titleBarBack.setOnClickListener(v -> finish());
    }

    /**
     * 初始化WebView地图
     */
    @SuppressLint("SetJavaScriptEnabled")
    private void initWebView() {
        WebSettings webSettings = mBinding.webView.getWebView().getSettings();
        webSettings.setJavaScriptEnabled(true);
        webSettings.setDomStorageEnabled(true);
        webSettings.setAllowFileAccess(true);
        webSettings.setAllowFileAccessFromFileURLs(true);
        webSettings.setAllowUniversalAccessFromFileURLs(true);

        // 设置WebViewClient
        mBinding.webView.getWebView().setWebViewClient(new WebViewClient());

        String url = "file:///android_asset/roadLine/index.html";
        WebSettings mWebSettings = mBinding.webView.getWebView().getSettings();
        mWebSettings.setJavaScriptEnabled(true);//设置支持javaScript
        mBinding.webView.loadUrl(url);
        // 添加JavaScript接口（如果需要与H5交互）
        // mBinding.webView.getWebView().addJavascriptInterface(new MapInterface(), "android");
    }

    /**
     * 初始化数据
     */
    private void initData() {
        // 设置默认巡查时间
        states.patrolTime.set(Kits.Date.getYmdhms(Calendar.getInstance().getTimeInMillis()));

        // 获取传递的巡查对象（从选择页面传递过来）
        String patrolObject = null;
        if (getIntent() != null) {
            patrolObject = getIntent().getStringExtra("patrolObject");
        }

        // 如果Intent中有传递，使用传递的值，否则从UserInfo获取
        if (patrolObject != null && !patrolObject.isEmpty()) {
            states.patrolObject.set(patrolObject);
        } else {
            String projectName = com.nsgf.library.data.bean.UserInfo.getInstance().getProjectName();
            if (projectName != null && !projectName.isEmpty()) {
                states.patrolObject.set(projectName);
            }
        }

        // 设置默认巡查人员（可以从UserInfo获取）
        String userName = com.nsgf.library.data.bean.UserInfo.getInstance().getName();
        if (userName != null && !userName.isEmpty()) {
            states.patrolPerson.set(userName);
        }

        // 初始化天气UI
        updateWeatherUI();

        // 初始化检查结果UI
        updateCheckResultUI();

        // 初始化异常情况显示状态
        updateAbnormalSituationVisibility();

        // 初始化结构组件列表
        initStructureComponents();

        mAdapter.setOnItemClickListener((viewId, item, position) -> {
            for (int i = 0; i < mAdapter.getCurrentList().size(); i++) {
                mAdapter.getCurrentList().get(i).setSelectWeather(false);
            }
            mAdapter.getCurrentList().get(position).setSelectWeather(true);
            mAdapter.notifyDataSetChanged();
        });

    }

    /**
     * 初始化观察者
     */
    private void initObserver() {
        getLifecycle().addObserver(mAccountRequester);
    }

    /**
     * 加载天气数据
     */
    private void loadWeatherData() {
        mAccountRequester.getDictItems("weather.type");
    }

    /**
     * 初始化结构组件列表
     */
    private void initStructureComponents() {
        structureComponentList.clear();
        structureComponentList.add(new StructureComponentBean("闸墩"));
        structureComponentList.add(new StructureComponentBean("边墙"));
        structureComponentList.add(new StructureComponentBean("胸墙"));
        structureComponentList.add(new StructureComponentBean("工作桥"));

        mStructureComponentAdapter.submitList(structureComponentList);
        states.structureComponentAdapter.set(mStructureComponentAdapter);


        // 记录第一次巡检时间
        Calendar calendar = Calendar.getInstance();
        states.patrolTime.set(Kits.Date.getYmdhmss(calendar.getTimeInMillis()));
        startTimer();

        String[] permission;


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                permission = new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION,
                        Manifest.permission.POST_NOTIFICATIONS,
                        Manifest.permission.ACCESS_FINE_LOCATION};
            } else {
                if (!isNotificationPermissionGranted()) {
                    showPermissionDialog();
                }
                permission = new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION,
                        Manifest.permission.ACCESS_FINE_LOCATION};
            }
        } else {
            permission = new String[]{Manifest.permission.ACCESS_FINE_LOCATION};
        }

        boolean checkPermissionFirst = PermissionsUtils.checkPermissionFirst(this, 1003, permission);

        if (checkPermissionFirst) {
            // 绑定到 Service
            Intent intent = new Intent(PatrolActivity.this, LocationService.class);
            // bindService() 用于绑定到 Service
            bindService(intent, mServiceConnection, BIND_AUTO_CREATE);
            // ignoreBatteryOptimization(ManagerWorkOrderDamDetailsActivity.this);
        } else {
            ToastUtils.showLongToast("请允许相关权限，否则无法完成任务");
        }

    }

    /**
     * 初始化图片选择器
     */
    private void initImagePicker() {
        Set<MimeType> mimeTypes = new HashSet<>();
        mimeTypes.add(MimeType.JPEG);
        mimeTypes.add(MimeType.PNG);
        mimeTypes.add(MimeType.GIF);

        mBinding.multiPickResultView.init(
                this,
                MultiPickResultView.ACTION_SELECT,  // 用于图片选择
                new ArrayList<WorkOrderDetailBean.FileDto>(),  // 初始图片列表（空）
                9,  // 最大选择数量
                0,  // index
                mimeTypes,
                new PhotoAdapter.PhotoOnClick() {
                    @Override
                    public void setPhotoListener(int position) {

                    }
                }
        );
    }

    /**
     * 打开视频选择器
     */
    private void openVideoPicker() {
        // 检查权限
        String[] permissions;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            // Android 13 (API 33) 及以上版本使用新的权限
            permissions = new String[]{
                    Manifest.permission.READ_MEDIA_VIDEO,
                    Manifest.permission.READ_MEDIA_IMAGES
            };
        } else {
            // Android 13 以下版本使用传统权限
            permissions = new String[]{
                    Manifest.permission.READ_EXTERNAL_STORAGE,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE
            };
        }

        boolean checkPermissionFirst = PermissionsUtils.checkPermissionFirst(this, 1004, permissions);
        if (!checkPermissionFirst) {
            ToastUtils.showLongToast("请允许存储权限，否则无法选择视频");
            return;
        }

        Set<MimeType> mimeTypes = MimeType.ofVideo();

        Matisse.from(this)
                .choose(mimeTypes, false)
                .capture(false)  // 不允许直接录制视频（如果需要可以改为true）
                .setSelectedImages(new ArrayList<>())  // 设置空列表，避免影响图片选择状态
                .maxSelectable(1)  // 最多选择1个视频
                .theme(R.style.Matisse_Dracula)  // 暗色主题
                .imageEngine(new com.nsgf.library.matisse.engine.impl.GlideEngine())
                .forResult(REQUEST_CODE_VIDEO);
    }

    /**
     * 更新视频显示
     */
    private void updateVideoDisplay() {
        LinearLayout videoListLayout = mBinding.llVideoList;
        videoListLayout.removeAllViews();
        // 允许子视图超出容器边界显示（重要：确保删除按钮不被裁剪）
        videoListLayout.setClipChildren(false);
        videoListLayout.setClipToPadding(false);

        if (selectedVideos != null && !selectedVideos.isEmpty()) {
            states.hasVideo.set(true);
            // 手动设置视图可见性，确保立即显示
            videoListLayout.setVisibility(View.VISIBLE);

            // 将dp转换为px
            float density = getResources().getDisplayMetrics().density;
            int videoSize = (int) (80 * density); // 80dp，与上传按钮一样大
            int deleteBtnSize = (int) (20 * density); // 20dp
            int playIconSize = (int) (24 * density); // 24dp，播放图标大小
            int marginRight = (int) (10 * density); // 10dp

            for (int i = 0; i < selectedVideos.size(); i++) {
                WorkOrderDetailBean.FileDto video = selectedVideos.get(i);

                // 创建视频预览视图容器
                RelativeLayout videoItemContainer = new RelativeLayout(this);
                RelativeLayout.LayoutParams containerParams = new RelativeLayout.LayoutParams(
                        videoSize,
                        videoSize
                );
                containerParams.setMargins(0, 0, marginRight, 0);
                videoItemContainer.setLayoutParams(containerParams);
                // 允许子视图超出容器边界显示（重要：确保删除按钮不被裁剪）
                videoItemContainer.setClipChildren(false);
                videoItemContainer.setClipToPadding(false);

                // 视频缩略图（使用MediaMetadataRetriever加载视频第一帧）
                android.widget.ImageView thumbnail = new android.widget.ImageView(this);
                RelativeLayout.LayoutParams thumbnailParams = new RelativeLayout.LayoutParams(
                        videoSize,
                        videoSize
                );
                thumbnail.setLayoutParams(thumbnailParams);
                thumbnail.setScaleType(android.widget.ImageView.ScaleType.CENTER_CROP);
                thumbnail.setBackgroundResource(R.drawable.bg_upload_button);

                // 使用MediaMetadataRetriever获取视频第一帧作为缩略图
                String videoPath = video.getFilePath();
                if (videoPath != null && !videoPath.isEmpty()) {
                    loadVideoThumbnail(thumbnail, videoPath, videoSize);
                }

                // 播放图标（居中显示）
                android.widget.ImageView playIcon = new android.widget.ImageView(this);
                RelativeLayout.LayoutParams playIconParams = new RelativeLayout.LayoutParams(
                        playIconSize,
                        playIconSize
                );
                playIconParams.addRule(RelativeLayout.CENTER_IN_PARENT);
                playIcon.setLayoutParams(playIconParams);
                playIcon.setImageResource(R.drawable.ic_play_circle_outline_white_48dp);
                playIcon.setBackgroundResource(android.R.color.transparent);

                // 删除按钮 - 放在容器内部，避免被遮挡
                android.widget.ImageView deleteBtn = new android.widget.ImageView(this);
                RelativeLayout.LayoutParams deleteParams = new RelativeLayout.LayoutParams(
                        deleteBtnSize,
                        deleteBtnSize
                );
                deleteParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
                deleteParams.addRule(RelativeLayout.ALIGN_PARENT_END);
                // 使用正边距，将删除按钮放在容器内部，距离边缘4dp
                int deleteMargin = (int) (4 * density); // 4dp的正边距，确保在容器内部
                deleteParams.setMargins(0, deleteMargin, deleteMargin, 0);
                deleteBtn.setLayoutParams(deleteParams);
                // 使用正确的删除图标
                deleteBtn.setImageResource(R.drawable.icon_delete);
                deleteBtn.setPadding((int) (2 * density), (int) (2 * density), (int) (2 * density), (int) (2 * density));
                // 设置 elevation 确保在最上层（API 21+）
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
                    deleteBtn.setElevation(10f * density); // 10dp elevation，确保在最上层
                }
                // 确保可点击
                deleteBtn.setClickable(true);
                deleteBtn.setFocusable(true);
                // 设置内容描述，提高可访问性
                deleteBtn.setContentDescription("删除视频");
                final int index = i;
                deleteBtn.setOnClickListener(v -> {
                    selectedVideos.remove(index);
                    if (selectedVideos.isEmpty()) {
                        states.hasVideo.set(false);
                    }
                    updateVideoDisplay();
                });

                videoItemContainer.addView(thumbnail);
                videoItemContainer.addView(playIcon);
                videoItemContainer.addView(deleteBtn);
                // 确保删除按钮在最上层
                deleteBtn.bringToFront();
                videoListLayout.addView(videoItemContainer);
            }
        } else {
            states.hasVideo.set(false);
            // 手动设置视图不可见，确保立即隐藏
            videoListLayout.setVisibility(View.GONE);
        }
    }

    /**
     * 加载视频缩略图
     */
    private void loadVideoThumbnail(android.widget.ImageView imageView, String videoPath, int size) {
        new Thread(() -> {
            MediaMetadataRetriever retriever = new MediaMetadataRetriever();
            try {
                retriever.setDataSource(videoPath);
                Bitmap bitmap = retriever.getFrameAtTime(0, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
                if (bitmap != null) {
                    // 在主线程更新UI
                    runOnUiThread(() -> {
                        Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, size, size, true);
                        imageView.setImageBitmap(scaledBitmap);
                        if (scaledBitmap != bitmap) {
                            bitmap.recycle();
                        }
                    });
                }
            } catch (Exception e) {
                Log.e("PatrolActivity", "加载视频缩略图失败: " + e.getMessage());
            } finally {
                try {
                    retriever.release();
                } catch (Exception e) {
                    Log.e("PatrolActivity", "释放MediaMetadataRetriever失败: " + e.getMessage());
                }
            }
        }).start();
    }

    /**
     * 打开图片选择器
     */
    private void openImagePicker() {
        Set<MimeType> mimeTypes = new HashSet<>();
        mimeTypes.add(MimeType.JPEG);
        mimeTypes.add(MimeType.PNG);
        mimeTypes.add(MimeType.GIF);

        // 获取已选中的图片路径
        ArrayList<WorkOrderDetailBean.FileDto> selectedPaths = new ArrayList<>();
        if (mBinding.multiPickResultView.getPhotos() != null) {
            for (WorkOrderDetailBean.FileDto photo : mBinding.multiPickResultView.getPhotos()) {
                if (photo != null && photo.getFilePath() != null && !photo.getFilePath().startsWith("http")) {
                    selectedPaths.add(photo);
                }
            }
        }

        Matisse.from(this)
                .choose(mimeTypes, false)
                .capture(true)  // 允许拍照
                .setSelectedImages(selectedPaths)  // 设置已选中的图片
                .captureStrategy(
                        new com.nsgf.library.matisse.internal.entity.CaptureStrategy(true, "com.nsgf.daye.fileprovider", "test"))
                .maxSelectable(9)  // 最大选择9张
                .theme(R.style.Matisse_Dracula)  // 暗色主题
                .originalEnable(true)  // 显示原图选项
                .imageEngine(new com.nsgf.library.matisse.engine.impl.GlideEngine())
                .forResult(PhotoPicker.REQUEST_CODE);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == RESULT_OK) {
            if (PhotoPicker.REQUEST_CODE == requestCode) {
                // 处理图片选择结果
                ArrayList<WorkOrderDetailBean.FileDto> photos = new ArrayList<>();

                // 获取新选择的图片路径
                for (String path : Matisse.obtainPathResult(data)) {
                    WorkOrderDetailBean.FileDto dto = new WorkOrderDetailBean.FileDto();
                    dto.setFilePath(path);
                    photos.add(dto);
                }

                // 将选择的图片传递给MultiPickResultView
                data.putExtra(KEY_SELECTED_PHOTOS, photos);
                mBinding.multiPickResultView.onActivityResult(requestCode, resultCode, data);
            } else if (REQUEST_CODE_VIDEO == requestCode) {
                // 处理视频选择结果
                List<String> videoPaths = Matisse.obtainPathResult(data);
                if (videoPaths != null && !videoPaths.isEmpty()) {
                    selectedVideos.clear();
                    for (String path : videoPaths) {
                        WorkOrderDetailBean.FileDto dto = new WorkOrderDetailBean.FileDto();
                        dto.setFilePath(path);
                        selectedVideos.add(dto);
                    }
                    // 更新视频显示
                    updateVideoDisplay();
                }
            }
        }
    }

    /**
     * 更新天气UI
     */
    private void updateWeatherUI() {

        mAccountRequester.getWeatherDetailResult().observe(this, new Observer<DataResult<WeatherBean>>() {
            @Override
            public void onChanged(DataResult<WeatherBean> dataResult) {

                if (dataResult.getResponseStatus().isSuccess()) {
                    if (200 == dataResult.getResult().getCode()) {
                        states.weatherList.set(dataResult.getResult().getData());
                    } else {

                        if (401 == dataResult.getResult().getCode()) {
                            UserInfo.getInstance().clearUserInfo();
                            finish();
                        }
                        ToastUtils.showLongToast(dataResult.getResult().getMsg());
                    }
                } else {
                    ToastUtils.showLongToast(getErrorMsg(dataResult.getResponseStatus().getE()));
                }
            }
        });
    }


    /**
     * 更新检查结果UI
     */
    private void updateCheckResultUI() {
        if (checkResult == 0) {
            mBinding.radioNormal.setChecked(true);
            mBinding.radioAbnormal.setChecked(false);
        } else {
            mBinding.radioNormal.setChecked(false);
            mBinding.radioAbnormal.setChecked(true);
        }
        // 更新异常情况部分的显示状态
        updateAbnormalSituationVisibility();
    }

    /**
     * 更新异常情况部分的显示/隐藏
     */
    private void updateAbnormalSituationVisibility() {
        states.showAbnormalSituation.set(checkResult == 1);
    }

    /**
     * 保存巡查记录
     */
    private void savePatrol() {
        // 验证必填字段
        if (states.waterLevel.get() == null || states.waterLevel.get().isEmpty()) {
            showToast("请输入内湖水位");
            return;
        }

        // 获取天气类型
        String weatherType = "";
        if (states.weatherList != null && !states.weatherList.get().isEmpty() && selectedWeatherIndex >= 0 && selectedWeatherIndex < states.weatherList.get().size()) {
            WeatherBean.DataBean selectedWeather = states.weatherList.get().get(selectedWeatherIndex);
            if (selectedWeather != null && selectedWeather.getItemValue() != null) {
                weatherType = selectedWeather.getItemValue();
            }
        }
        if (weatherType.isEmpty()) {
            showToast("请选择天气");
            return;
        }

        // 如果选择异常，验证异常情况必填字段
        if (checkResult == 1) {
            if (states.situationRecord.get() == null || states.situationRecord.get().isEmpty()) {
                showToast("请输入情况记录");
                return;
            }
        }

        // 构建JSON请求体
        JsonObject jsonObject = new JsonObject();

        // 基础信息
        jsonObject.addProperty("patrolObject", states.patrolObject.get() != null ? states.patrolObject.get() : "");
        jsonObject.addProperty("patrolPerson", states.patrolPerson.get() != null ? states.patrolPerson.get() : "");
        jsonObject.addProperty("patrolTime", states.patrolTime.get() != null ? states.patrolTime.get() : "");
        jsonObject.addProperty("waterLevel", states.waterLevel.get() != null ? states.waterLevel.get() : "");
        jsonObject.addProperty("weather", weatherType);
        jsonObject.addProperty("patrolDuration", states.patrolDuration.get() != null ? states.patrolDuration.get() : "");
        jsonObject.addProperty("patrolDistance", states.patrolDistance.get() != null ? states.patrolDistance.get() : "");

        // 检查结果
        jsonObject.addProperty("checkResult", checkResult == 0 ? "正常" : "异常");

        // 如果选择异常，添加异常情况相关字段
        if (checkResult == 1) {
            // 情况记录
            jsonObject.addProperty("situationRecord", states.situationRecord.get() != null ? states.situationRecord.get() : "");

            // 结构组件检查项
            JsonArray structureComponents = new JsonArray();
            for (StructureComponentBean component : structureComponentList) {
                JsonObject componentObj = new JsonObject();
                componentObj.addProperty("componentName", component.getComponentName());
                JsonArray selectedItems = new JsonArray();
                List<String> selectedItemNames = component.getSelectedCheckItemNames();
                for (String itemName : selectedItemNames) {
                    selectedItems.add(itemName);
                }
                componentObj.add("checkItems", selectedItems);
                structureComponents.add(componentObj);
            }
            jsonObject.add("structureComponents", structureComponents);

            // 图片列表
            JsonArray photos = new JsonArray();
            if (mBinding.multiPickResultView.getPhotos() != null) {
                for (WorkOrderDetailBean.FileDto photo : mBinding.multiPickResultView.getPhotos()) {
                    if (photo != null && photo.getFilePath() != null) {
                        JsonObject photoObj = new JsonObject();
                        photoObj.addProperty("fileName", photo.getFileName() != null ? photo.getFileName() : "");
                        photoObj.addProperty("filePath", photo.getFilePath());
                        photoObj.addProperty("fileSize", photo.getFileSize());
                        photos.add(photoObj);
                    }
                }
            }
            jsonObject.add("photos", photos);

            // 视频列表
            JsonArray videos = new JsonArray();
            if (selectedVideos != null && !selectedVideos.isEmpty()) {
                for (WorkOrderDetailBean.FileDto video : selectedVideos) {
                    if (video != null && video.getFilePath() != null) {
                        JsonObject videoObj = new JsonObject();
                        videoObj.addProperty("fileName", video.getFileName() != null ? video.getFileName() : "");
                        videoObj.addProperty("filePath", video.getFilePath());
                        videoObj.addProperty("fileSize", video.getFileSize());
                        videos.add(videoObj);
                    }
                }
            }
            jsonObject.add("videos", videos);
        }

        // TODO: 调用保存接口
        // 创建RequestBody并调用API
        MediaType mediaType = MediaType.parse("application/json;charset=UTF-8");
        RequestBody requestBody = RequestBody.create(mediaType, jsonObject.toString());

        // 暂时打印日志，实际需要调用保存接口
        android.util.Log.d("PatrolActivity", "保存数据: " + jsonObject.toString());
        showToast("保存成功");

        // 如果需要调用API，可以在这里调用
        // mAccountRequester.savePatrolRecord(requestBody);
    }

    /**
     * 提交巡查记录
     */
    private void submitPatrol() {
        // 验证必填字段
        if (states.waterLevel.get() == null || states.waterLevel.get().isEmpty()) {
            showToast("请输入内湖水位");
            return;
        }

        // 获取天气类型
        String weatherType = "";
        if (states.weatherList != null && !states.weatherList.get().isEmpty() && selectedWeatherIndex >= 0 && selectedWeatherIndex < states.weatherList.get().size()) {
            WeatherBean.DataBean selectedWeather = states.weatherList.get().get(selectedWeatherIndex);
            if (selectedWeather != null && selectedWeather.getItemValue() != null) {
                weatherType = selectedWeather.getItemValue();
            }
        }
        if (weatherType.isEmpty()) {
            showToast("请选择天气");
            return;
        }

        // 如果选择异常，验证异常情况必填字段
        if (checkResult == 1) {
            if (states.situationRecord.get() == null || states.situationRecord.get().isEmpty()) {
                showToast("请输入情况记录");
                return;
            }
        }

        // 收集需要上传的文件（只上传本地路径的文件，跳过已经是http的）
        List<FileInfo> filesToUpload = new ArrayList<>();
        List<WorkOrderDetailBean.FileDto> uploadedPhotos = new ArrayList<>();
        List<WorkOrderDetailBean.FileDto> uploadedVideos = new ArrayList<>();

        // 收集图片文件
        if (mBinding.multiPickResultView.getPhotos() != null) {
            for (WorkOrderDetailBean.FileDto photo : mBinding.multiPickResultView.getPhotos()) {
                if (photo != null && photo.getFilePath() != null) {
                    if (photo.getFilePath().startsWith("http")) {
                        // 已经是服务器路径，直接添加到已上传列表
                        uploadedPhotos.add(photo);
                    } else {
                        // 本地路径，需要上传
                        filesToUpload.add(new FileInfo(photo.getFilePath(), true));
                    }
                }
            }
        }

        // 收集视频文件
        if (selectedVideos != null && !selectedVideos.isEmpty()) {
            for (WorkOrderDetailBean.FileDto video : selectedVideos) {
                if (video != null && video.getFilePath() != null) {
                    if (video.getFilePath().startsWith("http")) {
                        // 已经是服务器路径，直接添加到已上传列表
                        uploadedVideos.add(video);
                    } else {
                        // 本地路径，需要上传
                        filesToUpload.add(new FileInfo(video.getFilePath(), false));
                    }
                }
            }
        }

        // 如果有文件需要上传，先批量上传
        if (!filesToUpload.isEmpty()) {
            uploadFilesAndSubmit(filesToUpload, uploadedPhotos, uploadedVideos, weatherType);
        } else {
            // 没有文件需要上传，直接提交
            submitPatrolData(uploadedPhotos, uploadedVideos, weatherType);
        }
    }

    /**
     * 文件信息类，用于记录文件路径和类型
     */
    private static class FileInfo {
        String filePath;
        boolean isPhoto; // true表示图片，false表示视频

        FileInfo(String filePath, boolean isPhoto) {
            this.filePath = filePath;
            this.isPhoto = isPhoto;
        }
    }

    /**
     * 批量上传文件并提交
     */
    private void uploadFilesAndSubmit(List<FileInfo> filesToUpload, List<WorkOrderDetailBean.FileDto> uploadedPhotos,
                                      List<WorkOrderDetailBean.FileDto> uploadedVideos, String weatherType) {
        showToast("正在上传文件...");

        // 使用队列来按顺序匹配上传结果（因为文件名会改变，无法通过文件名匹配）
        final Queue<FileInfo> uploadQueue = new LinkedList<>(filesToUpload);
        final int[] uploadCount = {0};
        final int totalCount = filesToUpload.size();
        final boolean[] hasError = {false};

        mAccountRequester.getNewFileInfo().observe(this, new Observer<ResponseStatus<WorkOrderDetailBean.FileDto>>() {
            @Override
            public void onChanged(ResponseStatus<WorkOrderDetailBean.FileDto> dataResult) {
                if (hasError[0]) {
                    return; // 如果已经有错误，不再处理后续结果
                }

                if (dataResult.getResponseCode() == 200) {
                    WorkOrderDetailBean.FileDto uploadedFile = dataResult.getData();
                    if (uploadedFile != null) {
                        // 从队列中取出第一个未匹配的文件（按上传顺序匹配）
                        FileInfo fileInfo = uploadQueue.poll();
                        if (fileInfo != null) {
                            uploadCount[0]++;

                            // 根据文件类型添加到对应列表
                            if (fileInfo.isPhoto) {
                                uploadedPhotos.add(uploadedFile);
                            } else {
                                uploadedVideos.add(uploadedFile);
                            }

                            // 所有文件上传完成
                            if (uploadCount[0] == totalCount) {
                                // 提交数据
                                submitPatrolData(uploadedPhotos, uploadedVideos, weatherType);
                            }
                        }
                    } else {
                        hasError[0] = true;
                        showToast("文件上传失败");
                    }
                } else {
                    hasError[0] = true;
                    showToast(dataResult.getMsg());
                }
            }
        });

        // 遍历上传每个文件
        for (FileInfo fileInfo : filesToUpload) {
            mAccountRequester.newUploadFile(fileInfo.filePath);
        }
    }

    /**
     * 提交巡查数据
     */
    private void submitPatrolData(List<WorkOrderDetailBean.FileDto> uploadedPhotos,
                                  List<WorkOrderDetailBean.FileDto> uploadedVideos,
                                  String weatherType) {
        // 构建JSON请求体
        JsonObject jsonObject = new JsonObject();

        // 基础信息
        jsonObject.addProperty("id", 0); // 新增传0，更新传实际ID
        jsonObject.addProperty("projectCode", com.nsgf.library.data.bean.UserInfo.getInstance().getProjectCode() != null ?
                com.nsgf.library.data.bean.UserInfo.getInstance().getProjectCode() : "");

        // 获取巡查人员ID（从UserInfo获取）
        String inspectorId = com.nsgf.library.data.bean.UserInfo.getInstance().getId() != null ?
                com.nsgf.library.data.bean.UserInfo.getInstance().getId() : "0";
        try {
            jsonObject.addProperty("inspector", Integer.parseInt(inspectorId));
        } catch (NumberFormatException e) {
            jsonObject.addProperty("inspector", 0);
        }

        // 巡查时间（格式化）
        String patrolTimeStr = states.patrolTime.get() != null ? states.patrolTime.get() : "";
        // 如果格式不对，需要转换
        if (patrolTimeStr.contains(":") && !patrolTimeStr.contains("-")) {
            // 可能是时长格式，需要获取实际时间
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
            patrolTimeStr = sdf.format(new Date());
        }
        jsonObject.addProperty("inspectTime", patrolTimeStr);

        jsonObject.addProperty("waterLevel", states.waterLevel.get() != null ? states.waterLevel.get() : "");
        jsonObject.addProperty("weather", weatherType);
        jsonObject.addProperty("isAbnormal", checkResult); // 0-正常 1-异常

        // 巡查结果和情况记录
        String inspectResult = checkResult == 0 ? "正常" : "异常";
        jsonObject.addProperty("inspectResult", inspectResult);
        jsonObject.addProperty("situationRecord", states.situationRecord.get() != null ? states.situationRecord.get() : "");

        // 记录图片和视频（拼接字符串，逗号分隔）
        StringBuilder recordImgBuilder = new StringBuilder();
        StringBuilder recordVideoBuilder = new StringBuilder();

        // 记录图片列表
        JsonArray recordImgList = new JsonArray();
        for (WorkOrderDetailBean.FileDto photo : uploadedPhotos) {
            if (photo != null && photo.getFilePath() != null) {
                JsonObject photoObj = new JsonObject();
                photoObj.addProperty("id", 0);
                photoObj.addProperty("filePath", photo.getFilePath());
                photoObj.addProperty("fileName", photo.getFileName() != null ? photo.getFileName() : "");
                photoObj.addProperty("createTime", "");
                photoObj.addProperty("createBy", 0);
                photoObj.addProperty("isDelete", 0);
                recordImgList.add(photoObj);

                if (recordImgBuilder.length() > 0) {
                    recordImgBuilder.append(",");
                }
                recordImgBuilder.append(photo.getFilePath());
            }
        }
        jsonObject.addProperty("recordImg", recordImgBuilder.toString());
        jsonObject.add("recordImgList", recordImgList);

        // 记录视频列表
        JsonArray recordVideoList = new JsonArray();
        for (WorkOrderDetailBean.FileDto video : uploadedVideos) {
            if (video != null && video.getFilePath() != null) {
                JsonObject videoObj = new JsonObject();
                videoObj.addProperty("id", 0);
                videoObj.addProperty("filePath", video.getFilePath());
                videoObj.addProperty("fileName", video.getFileName() != null ? video.getFileName() : "");
                videoObj.addProperty("createTime", "");
                videoObj.addProperty("createBy", 0);
                videoObj.addProperty("isDelete", 0);
                recordVideoList.add(videoObj);

                if (recordVideoBuilder.length() > 0) {
                    recordVideoBuilder.append(",");
                }
                recordVideoBuilder.append(video.getFilePath());
            }
        }
        jsonObject.addProperty("recordVideo", recordVideoBuilder.toString());
        jsonObject.add("recordVideoList", recordVideoList);

        // 处理措施相关字段（如果UI中有输入，可以从states中获取，否则传空）
        jsonObject.addProperty("handleMeasure", "");
        jsonObject.addProperty("handleImg", "");
        jsonObject.addProperty("handleVideo", "");
        jsonObject.add("handleImgList", new JsonArray());
        jsonObject.add("handleVideoList", new JsonArray());

        Log.d("PatrolActivity", "提交数据: " + jsonObject.toString());

        // 调用提交接口
        mAccountRequester.saveOrUpdatePatrolInfo(jsonObject);

        // 监听提交结果
        mAccountRequester.getStringResult().observe(this, dataResult -> {
            if (dataResult != null && dataResult.isSuccess()) {
                showToast("提交成功");
                finish(); // 提交成功后关闭页面
            } else {
                String errorMsg = dataResult != null ? dataResult.getMsg() : "提交失败";
                showToast(errorMsg);
            }
        });
    }

    /**
     * 点击事件代理
     */
    public class ClickProxy {
        public void onBackClick() {
            finish();
        }

        public void onWeatherClick(int index) {
            selectedWeatherIndex = index;
            updateWeatherUI();
        }

        public void onCheckResultClick(View view) {
            RadioButton radioButton = (RadioButton) view;
            if (radioButton.getId() == R.id.radioNormal) {
                checkResult = 0;
            } else if (radioButton.getId() == R.id.radioAbnormal) {
                checkResult = 1;
            }
            updateCheckResultUI();
        }

        public void onImageUploadClick() {
            // 检查权限并打开图片选择器
            openImagePicker();
        }

        public void onVideoUploadClick() {
            // 打开视频选择器
            openVideoPicker();
        }

        public void onSaveClick() {
            savePatrol();
        }

        public void onSubmitClick() {
            submitPatrol();
        }
    }

    /**
     * States
     */
    public static class PatrolStates extends StateHolder {
        public final State<String> titleBar = new State<>("工程巡查");

        // 巡查信息
        public final State<String> patrolObject = new State<>(""); // 巡查对象
        public final State<String> patrolPerson = new State<>(""); // 巡查人员
        public final State<String> patrolTime = new State<>(""); // 巡查时间
        public final State<String> waterLevel = new State<>(""); // 内湖水位
        public final State<String> patrolDuration = new State<>("0min"); // 巡查时长
        public final State<String> patrolDistance = new State<>("0m"); // 巡查距离

        // 巡查结果
        public final State<String> checkResult = new State<>("正常"); // 检查结果
        public final State<List<WeatherBean.DataBean>> weatherList = new State<List<WeatherBean.DataBean>>(null);

        // 异常情况
        public final State<Boolean> showAbnormalSituation = new State<>(false); // 是否显示异常情况部分
        public final State<String> situationRecord = new State<>(""); // 情况记录
        public final State<Boolean> hasVideo = new State<>(false); // 是否有视频
        public final State<StructureComponentAdapter> structureComponentAdapter = new State<>(null); // 结构组件适配器
    }


    private boolean isBound = false;
    LocationService myService;
    /**
     * 实际巡查路线
     */
    private List<List> actualRoute = new ArrayList<List>();
    private ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder iBinder) {
            Log.e("巡查定位：", "绑定回调");
            LocationService.Binder binder = (LocationService.Binder) iBinder;
            myService = binder.getService();
            // 绑定成功回调
            isBound = true;
            myService.setCallback(new LocationService.Callback() {
                @Override
                public void onDataChange(Location location) {

                    // 当位置更新时，这里处理位置信息
                    double latitude = location.getLatitude();
                    double longitude = location.getLongitude();

                    List<String> list = new ArrayList<>();
                    list.add(String.valueOf(longitude));
                    list.add(String.valueOf(latitude));
                    actualRoute.add(list);
//
//                    if (null != workOrderDetailBean) {
//                        workOrderDetailBean.getData().setActualRoute(actualRoute.toString());
//                    }
//                    bean.setActualRoute(actualRoute.toString());
                    patrolLine();

                }
            });
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            isBound = false;
            myService = null;
            Log.e("巡查定位：", "解绑回调");
        }
    };


    /**
     * @return
     */
    private void patrolLine() {

        JSONArray jsonArray = new JSONArray();
        for (int i = 0; i < actualRoute.size(); i++) {
            String[] doubles = actualRoute.get(i).toString()
                    .replace("[", "")
                    .replace("]", "").split(",");
            WorkOrderDetailBean.DataBean.PositionVOSBean positionVOSBean = new WorkOrderDetailBean.DataBean.PositionVOSBean();
            positionVOSBean.setLat(doubles[1]);
            positionVOSBean.setLon(doubles[0]);
            JSONObject initJson = getJsonObject(positionVOSBean);
            jsonArray.add(initJson);
        }

        //绘制巡查初始路线
//        callJavaScriptDrawPatrolLineFunction(jsonArray);
        calculateDistance(jsonArray);
    }

    //保留两位小数
    private DecimalFormat df = new DecimalFormat("#####0.00");

    /**
     * 计算巡查总里程
     */
    private void calculateDistance(JSONArray list) {
        double distance = 0.0;

        for (int i = 1; i < list.size(); i++) {
            distance = distance
                    + Utils.calculateDistance(Double.parseDouble(((JSONObject) list.get(i)).getString("lat").toString()),
                    Double.parseDouble(((JSONObject) list.get(i)).getString("lon").toString()),
                    Double.parseDouble(((JSONObject) list.get(i - 1)).getString("lat").toString()),
                    Double.parseDouble(((JSONObject) list.get(i - 1)).getString("lon").toString()));
        }

        states.patrolDistance.set(df.format(distance / 1000) + "km");

    }
}

